package interview.customListenListAdd;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * @author: 李德才
 * @description:
 * @create: 2020-12-12 18:10
 **/
public class Test03_CountDownLatch {

    volatile List<Object> lists = new ArrayList<>();

    public void add(Object o) {
        lists.add(o);
    }

    public int size() {
        return lists.size();
    }

    public static void main(String[] args) {

        /**
         * 使用 CountDownLatch 门闩
         * t2 启动，监听 size ,然后释放锁
         * t1 启动，开始添加
         * t1 添加到5 调用 countDown
         * t2 中的程序可以执行
         * 问题：程序执行需要时间，t1 通知了 t2 执行，
         * 但是有可能在 t2 执行之前 ，t1 又添加了数据，
         * 这就会导致 t2 输出不正确
         * ----------------------
         * 解决方案：用两只门闩
         */
        Test03_CountDownLatch c = new Test03_CountDownLatch();
        CountDownLatch latch = new CountDownLatch(1);
        CountDownLatch latch2 = new CountDownLatch(1);
        new Thread(() -> {
            System.out.println("t2启动");
            if (c.size() != 5) {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("t2 结束");
            latch2.countDown();
        }, "t2").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        new Thread(() -> {
            System.out.println("t1启动");
            for (int i = 0; i < 10; i++) {
                c.add(new Object());
                System.out.println("add " + i);
                if (c.size() == 5) {
                    latch.countDown();
                    try {
                        latch2.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        }, "t1").start();

    }

}
